/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.war.metier;

import com.ejb.metier.IBookManager;
import com.ejb.persistence.Author;
import com.ejb.persistence.Book;
import com.ejb.persistence.BookCategory;
import com.war.session.UserSession;
import java.util.ArrayList;
import java.util.List;
import javax.ejb.EJB;
import javax.el.ELContext;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.RequestScoped;
import javax.faces.context.FacesContext;

/**
 * 
 * @author Ambroise
 * Class used to manage books
 */
@ManagedBean(name="bookManager")
@RequestScoped
public class BookManager {
    
    private static final String ALL_CATEGORIES= "Toutes catégories";
    @EJB
    private IBookManager bookManagerBean;
    private ELContext elContext = FacesContext.getCurrentInstance().getELContext();
	private List<Long> authorsId;
	/**
	 * Import the UserSession.
	 */
	private UserSession session = (UserSession) FacesContext.getCurrentInstance().getApplication().getELResolver().getValue(elContext, null, "userSession");
    
    private List<String> categories;
    private String category;
    private String searchString;
    private String firstName;
    private String lastName;
    
    /**
     * Creates a new instance of BookManager
     */
    public BookManager() {
    }
    
    /**
     * Calls the BookManagerBean to get the best sells.
     * @return List<Book>: A list of books.
     */
    public List<Book> getMostSoldBooks(){
        return this.bookManagerBean.getMostSold();
    }

    /**
     * Set the book received as the book stored in the UserSession.
     * This book in session will determine which book will be displayed in the book.xhtml page.
     * @param book
     * @return The String of page to load.
     */
    public String loadBook(Book book){
        session.setBook(book);
        return "book?faces-redirect=true";
    }
    
    /**
     * Set the book list in UserSession to all available books in the database.
     * @return The String of page to load.
     */
    public String loadAllBooks(){
        this.session.setBooks(this.bookManagerBean.getAllBooks());
        return "library?faces-redirect=true";
    }
    /**
     * Set the book list in UserSession to all available books with the needed category.
     * @param category
     * @return 
     */
    public String loadBooksByCategory(String category){
        if (category.equals(ALL_CATEGORIES)){
            loadAllBooks();
        }else {
            this.session.setBooks(this.bookManagerBean.getBooksByCategory(BookCategory.valueOf(category)));
        }
        return "";
    }
    
    /**
     * Returns a String corresponding to all the authors of a book.
     * Each author is separated by " & "
     * @param book
     * @return The authors as one string.
     */
    public String getBookAuthors(Book book){
        String authors = "";
        List<Author> auths = this.bookManagerBean.getBookAuthors(book.getId());
        authors += auths.get(0).getFirstName() + " " + auths.get(0).getLastName();
        if (auths.size() > 1){
            for (int i = 1; i<auths.size(); i++){
                authors += " & " + auths.get(i).getFirstName() + " " + auths.get(i).getLastName();
            }
        }
        return authors;
    }
    
    public int countAuthorsByBook(Book book){
        return book.getAuthors().size();
    }
    
    /**
     * 
     * @param book
     * @return 
     */
    public List<Author> getAllAuthors(){
        
//        if(book != null){
//            List<Author> bAuthors = bookManagerBean.getBookAuthors(book.getId());
//            this.authorsId = new ArrayList<Long>();
//            for (Author a:bAuthors){
//                authorsId.add(a.getId());
//            }
//        }
        List<Author> authors = this.bookManagerBean.getAllAuthors();

        return authors;
    }
    
    /**
     * Returns a String corresponding to all the authors of a book.
     * Each author is separated by " & "
     * @param book
     * @param separator Separator used under lines.
     * @return The authors as one string.
     */
    public String getBookAuthors(Book book, String separator, boolean onlyOneDisplay){
        return getBookAuthors(book, separator, onlyOneDisplay, false);
    }
    
    /**
     * Returns a String corresponding to all the authors of a book.
     * Each author is separated by " & "
     * @param book
     * @param separator Separator used under lines.
     * @param onlyOneDisplay If true, display only one line. Generate HTML content for display others authors when the mouse is over.
     * @param useSeparatorInFirstLine If true, jump the first line too. Else, jump all line but not the first.
     * @return The authors as one string.
     */
    public String getBookAuthors(Book book, String separator, boolean onlyOneDisplay, boolean useSeparatorInFirstLine){
        // If no  need display only one author, use basic getBookAuthors().
        if(!onlyOneDisplay && separator == null){
            return separator + getBookAuthors(book);
        }else if(!onlyOneDisplay){
            List<Author> auths = this.bookManagerBean.getBookAuthors(book.getId());

            // If there is several authors, display only one.
            if(auths.size() > 1){
                String authors = "";

                for (int i = 0; i < auths.size(); i++){
                    authors += ((useSeparatorInFirstLine)? separator : ((i == 0)? "" : separator)) + auths.get(i).getFirstName() + " " + auths.get(i).getLastName();
                }
                
                return authors;
            }else{
                // Use basic getBookAuthors().
                return getBookAuthors(book);
            }
        }else{
            List<Author> auths = this.bookManagerBean.getBookAuthors(book.getId());

            // If there is several authors, display only one.
            if(auths.size() > 1){
                String authors = "<span class='doPopoverTop blue b' title='Auteurs' data-content='";

                for (int i = 0; i < auths.size(); i++){
                    authors += ((useSeparatorInFirstLine)? separator :((i == 0)? "" : separator)) + auths.get(i).getFirstName() + " " + auths.get(i).getLastName();
                }

                authors+= "'>Voir</span>";

                return authors;
            }else{
                // Use basic getBookAuthors().
                return separator + getBookAuthors(book);
            }
        }
    }
    
    /**
     * Method used by the main research form. Get books by keyword or by keywor AND category.
     * @return The path of the file to load.
     */
    public String findBooks(){
        String retour = "search?faces-redirect=true";
        
        // If the category is not selected, get books by keyword only.
        if (category.equals(ALL_CATEGORIES)){
            this.session.setBooks(this.bookManagerBean.getBooks("key", this.searchString, null));
        }else {
            // Else, get books by category and keyword.
            this.session.setBooks(this.bookManagerBean.getBooks("category", this.searchString, BookCategory.valueOf(this.category)));
        }        

        return retour;
    }
     
    public List<Book> loadAdminBooks(){
        List<Book> books = this.bookManagerBean.getAllBooks();
        this.session.setBooks(books);
        return books;
    }
    
    public String removeBook(Book book){
        book.setAvailable(Boolean.FALSE);
        bookManagerBean.updateBook(book, null);
        return "administrationBooks";
    }
    
    public String updateBook(Book book){
        bookManagerBean.updateBook(book, this.session.getAuthorsId());
        System.out.println(this.session.getAuthorsId());
        this.session.setAuthorsId(null);
        return "administrationBooks?faces-redirect=true";
    }
    
    public String addBook(Book book){
        bookManagerBean.insertBook(book.getTitle(), book.getPrice(), book.getStock(), book.getThreshold(), "", book.getEditor(), 
                book.getPublicationDate(), book.getSummary(), book.getContents(), true, this.session.getAuthorsId(), book.getCategory());
        System.out.println(this.session.getAuthorsId());
        this.session.setAuthorsId(null);
        return "administrationBooks?faces-redirect=true";
    }
    
    public String editBookForm(Book book){
        this.session.setBook(book);
        this.session.setAuthorsId(null);
        return "administrationEditBook?faces-redirect=true";
    }
    /**
     * Returns a list of books where their stock are less or equal than their threshold.
     * @return 
     */
    public List<Book> loadBookUnderThreshold(){
        return bookManagerBean.getStockUnderThreshold();
    }
    
    public String updateStock(Book book){
        bookManagerBean.updateBook(book, null);
        return "administrationMonitoringStocks";
    }
    
    public String createBookForm(){
        this.session.setBook(new Book());
        this.session.setAuthorsId(null);
        return "administrationEditBook?faces-redirect=true";
    }
    
    public String addAuthor(){
        bookManagerBean.createAuthors(this.firstName, this.lastName);
        this.firstName = "";
        this.lastName = "";
        return "administrationEditBook";
    }
    
    public List<String> getCategories() {
        categories = new ArrayList<String>();
        categories.add(ALL_CATEGORIES);

        for (BookCategory cat: BookCategory.values()){
            categories.add(cat.name());
        }
        return categories;
    }
    
    public void setCategories(List<String> categories) {
        this.categories = categories;
    }
    
    public BookCategory[] getCategoriesEnum() {
        return BookCategory.values();
    }
    
    public String getCategory() {
        return category;
    }

    public void setCategory(String category) {
        this.category = category;
    }
    
    public String getSearchString() {
        return searchString;
    }

    public void setSearchString(String searchString) {
        this.searchString = searchString;
    }

    public List<Long> getAuthorsId() {
        return authorsId;
    }

    public void setAuthorsId(List<Long> authorsId) {
        this.authorsId = authorsId;
    }

    public String getFirstName() {
        return firstName;
    }

    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }

    public String getLastName() {
        return lastName;
    }

    public void setLastName(String lastName) {
        this.lastName = lastName;
    }
    
}
